#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <time.h>
#include "msg_queue.h"

// 模块名称定义
// #define MSG_QUEUE_MODULE "消息队列"

// 全局变量，消息队列ID
int g_msg_queue_id = -1;

// 初始化消息队列，传入key值，返回消息队列ID
int init_msg_queue(key_t key) {
    // 创建或获取消息队列
    g_msg_queue_id = msgget(key, IPC_CREAT | 0666);
    if (g_msg_queue_id == -1) {
        LOG_ERROR(LOG_TO_FILE, LOG_MODULE_MSGQ, "创建消息队列失败: %s", strerror(errno));
        return -1;
    }

    LOG_INFO(LOG_TO_FILE, LOG_MODULE_MSGQ, "消息队列初始化成功，ID: %d", g_msg_queue_id);
    return g_msg_queue_id;
}

// 发送消息到队列，第一个参数是队列ID
int send_msg(int queue_id, long msg_type, const char *msg_text) {
    struct msg_data message;
    
    // 检查队列ID是否有效
    if (queue_id < 0) {
        LOG_ERROR(LOG_TO_FILE, LOG_MODULE_MSGQ, "发送消息失败: 无效的队列ID %d", queue_id);
        return -1;
    }
    
    // 设置消息类型
    message.msg_type = msg_type;
    
    // 设置消息内容
    strncpy(message.msg_text, msg_text, sizeof(message.msg_text) - 1);
    message.msg_text[sizeof(message.msg_text) - 1] = '\0';
    
    // 发送消息
    if (msgsnd(queue_id, &message, sizeof(message.msg_text), IPC_NOWAIT) == -1) {
        LOG_ERROR(LOG_TO_FILE, LOG_MODULE_MSGQ, "发送消息失败: %s", strerror(errno));
        return -1;
    }
    
    LOG_DEBUG(LOG_TO_CONSOLE_ONLY, LOG_MODULE_MSGQ, "发送消息成功，队列ID: %d，类型: %ld", queue_id, msg_type);
    return 0;
}

// 接收消息从队列，第一个参数是队列ID
int recv_msg(int queue_id, long msg_type, struct msg_data *msg, int wait_flag) {
    int flags = 0;
    int ret;
    
    // 检查队列ID是否有效
    if (queue_id < 0) {
        LOG_ERROR(LOG_TO_FILE, LOG_MODULE_MSGQ, "接收消息失败: 无效的队列ID %d", queue_id);
        return -1;
    }
    
    // 设置接收标志
    if (!wait_flag) {
        flags = IPC_NOWAIT;  // 非阻塞模式
    }
    
    // 接收消息
    ret = msgrcv(queue_id, msg, sizeof(msg->msg_text), msg_type, flags);
    if (ret == -1) {
        if (errno == ENOMSG && !wait_flag) {
            // 非阻塞模式下没有消息，不是错误
            return 0;
        }
        LOG_ERROR(LOG_TO_FILE, LOG_MODULE_MSGQ, "接收消息失败: %s", strerror(errno));
        return -1;
    }
    
    LOG_DEBUG(LOG_TO_CONSOLE_ONLY, LOG_MODULE_MSGQ, "接收消息成功，队列ID: %d，类型: %ld，长度: %d", queue_id, msg->msg_type, ret);
    return ret;
}

// 获取消息队列ID
int get_msg_queue_id(void) {
    return g_msg_queue_id;
} 